#include "terrain.h"


void Initialiser_terrain(Terrain* T)
{
	T->DimX = TAILLE_X;
	T->DimY = TAILLE_Y;

	int  i,j;
	for ( i = 0 ; i < TAILLE_X; i++ )
	{
		for ( j = 0 ; j < TAILLE_Y; j++ )
		{
			T->ter[i][j] == NULL;
		}
	}
}

int Position_est_correcte(int x, int y)
{
	if ( x < 0) return FALSE; //! on ne peut pas être à gauche du terrain */
	if ( x > TAILLE_X ) return FALSE; //! on ne peut pas être à droite du terrain */
 	if ( y > TAILLE_Y-1 ) return FALSE; //! on ne peut pas être en bas du terrain */
 	//! par contre on peut se placer en y>0, la piece peut se trouver en partie en haut du terrain pour y<0 */
	return TRUE;
}

Piece* Get_Piece_X_Y(Terrain* T, int x, int y)
{
	return T->ter[x][y];
}

int Get_DimX_terrain(Terrain* T)
{
	return T->DimX;
}

int Get_DimY_terrain(Terrain* T)
{
	return T->DimY;
}

/*FONCTION A REVOIR
* Remarque quant à la fonction de suppression de ligne : des erreurs de positionement sont présentes dans toutes les
* fonctions (confusions x/y, problèmes d'offset, etc) il est probable qu'elle ne marche
* pas du premier coup.
*/


void Supprimer_ligne (Terrain* T, int l)
{
	int x;
	for ( x = 0 ; x < TAILLE_X ; x++ )
	{
		Piece* rencontree = T->ter[x][l];
		if ( rencontree != NULL )
		{
			/* on chercher les coordonnées de l'élement supprimé relativement à la piece */
			int p_x = rencontree->PosX_piece; /* utile ? */
			int p_y = rencontree->PosY_piece;
			/* il faut postion_relative + PosY_piece = l */
			int position_relative = l - p_y;
			int i;
			for ( i = 0 ; i < MAX_TAILLE_PIECE_Y ; i++ )
			{
				if ( rencontree->forme[position_relative][i] == 1 )
			/* cet element de la piece est sur la ligne qu'on veut supprimer*/
				{
					T->ter[x+i][l] == NULL;
					rencontree->forme[position_relative][i] == 0;
				}
			}
			if ( est_vide(rencontree) ) /* la piece est vide, on peut la supprimer*/
			{
				Detruire_piece(rencontree);
			}
			else /* la piece n'est pas vide, il faut donc la couper en deux */
			{
				Piece* nouvelle = Creer_piece();
				int partie_basse[MAX_TAILLE_PIECE_X][MAX_TAILLE_PIECE_Y] = {0};
				int p_y_bas = l + 1;
				int X, Y;
				for ( X = 0 ; X < MAX_TAILLE_PIECE_X ; X++)
					for (Y = position_relative + 1; Y < MAX_TAILLE_PIECE_Y ; Y++)
					{
						if ( rencontree->forme[X][Y] == 1 )
						{
							rencontree->forme[X][Y] = 0;
							partie_basse[X-(position_relative + 1)][Y] = 1;
							T->ter[X+p_x][p_y + Y] == nouvelle;
						}
					}
				Initialiser_piece(nouvelle, rencontree->c, partie_basse);
				nouvelle->PosX_piece = p_x;
				nouvelle->PosY_piece = p_y_bas;
				/* warning sur cette ligne int** != tableau d'entier à deux dimension ?*/
				if ( est_vide(nouvelle) )
				{
					Detruire_piece(nouvelle);
				}
				if ( est_vide(rencontree) )
				{
					Detruire_piece(rencontree);
				}
			}
		}


	}
}


int chercher_ligne_pleine(Terrain* T)
{
	int i, j;
	for ( i = TAILLE_Y - 1 ; i >= 0 ; i--)
	{
		int compteur = 0;
		for ( j = 0 ; j < TAILLE_X ; j++ )
		{
			if ( T->ter[j][i] != NULL ) compteur++;
		}
		if (compteur == TAILLE_X ) return i;
	}
	return 0;
}

int Ajouter_piece(Terrain* T, Piece* P)
{
	P->PosX_piece = ((TAILLE_X - MAX_TAILLE_PIECE_X) /2);
	P->PosY_piece = - MAX_TAILLE_PIECE_Y;
	if (Test_collision(P, T, BAS)) /* on peut insérer la piece */
	{
		Deplacer_piece(P, T, BAS);
		return TRUE;
	}
	else /* on ne peut pas insérer la pièce */
	{
		Detruire_piece(P);
		return FALSE; /* fin du jeu */
	}
}

void Deplacer_piece(Piece* P, Terrain* T, Direction D)
{
	int i, j;
	int x = P->PosX_piece;
	int y = P->PosY_piece;
	int d_x = 0;
	int d_y = 0;

	switch(D)
	{
		case BAS: d_y=1;
		break;
		case DROITE: d_x=1;
		break;
		case GAUCHE: d_x=-1;
		break;
		default: break;
	};

	for ( i = 0 ; i < MAX_TAILLE_PIECE_X; i++ )
		for ( j = 0 ; j < MAX_TAILLE_PIECE_Y; j++ )
		{
			if ( P->forme[i][j] == 1 ) /* case non vide */
			{
				int Position_relle_X = x + i;
				int Position_relle_Y = y + j;
				T->ter[Position_relle_X + d_x][Position_relle_Y + d_y] = P;
				T->ter[Position_relle_X][Position_relle_Y] = NULL;
			}
			else
			{
				/* rien à vérifier */
			}
 		}
	P->PosX_piece = x + d_x;
	P->PosY_piece = y + d_y;

}
int Test_collision(Piece* P, Terrain* T, Direction D)
{

	int x = P->PosX_piece;
	int y = P->PosY_piece;
	//printf("x = %d y= %d\n", x,y);

	switch(D)
	{
		case BAS: y+=1;
		break;
		case DROITE: x+=1;
		break;
		case GAUCHE: x-=1;
		break;
		default: break;
	};

	for ( i = 0 ; i < MAX_TAILLE_PIECE_X; i++ )
		for ( j = 0 ; j < MAX_TAILLE_PIECE_Y; j++ )
		{
			if ( P->forme[i][j] == 1 ) /* case non vide */
			{
				int Position_relle_X = x + i;
				int Position_relle_Y = y + j;
				//printf("Rx = %d Ry = %d",Position_relle_X,Position_relle_Y );
				if (Position_est_correcte(Position_relle_X,Position_relle_Y))/* on s'assure que la pièce reste bien dans le terrain */
				{
					if (( T->ter[Position_relle_X][Position_relle_Y] != NULL ) && ( T->ter[Position_relle_X][Position_relle_Y] != P ))
					{
						return FALSE;
					}
					else
					{
						/* rien */
					}
				}
				else
				{
					return FALSE;
				}
			}
			else
			{
				/* rien à vérifier */
			}
 		}
	return TRUE;
}

void Effacer_terrain(Terrain* T)
{
	int i, j;
	for ( i = 0 ; i < TAILLE_X ; i++)
		for ( j = 0 ; j < TAILLE_Y ; j++)
		{
			Piece* a_liberer = T->ter[i][j];
			if ( a_liberer != NULL ) /* il faut liberer */
			{
				int k,l;
				for ( k = 0 ; k < MAX_TAILLE_PIECE_X ; k++ )
					for ( l = 0 ; l < MAX_TAILLE_PIECE_Y ; l++ )
						if ( a_liberer->forme[k][l] == 1 ) T->ter[i+k][j+l-a_liberer->PosX_piece + 2] = NULL;
			}
			Detruire_piece(a_liberer);
		}
}

void afficher_terrain(Terrain* T)
{
	int i, j;
	for ( i = 0 ; i < TAILLE_X ; i++)
	{
		for ( j = 0 ; j < TAILLE_Y ; j++)
		{
			printf("%d",T->ter[i][j] != NULL);
		}
	printf("\n");
	}
}


